<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Command Grammar Lines</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
	tex: {
		inlineMath: '$', '$'], ['\\(', '\\)'
	},
	svg: {
		fontCache: 'global'
	}
};
</script>
<script type="text/javascript" id="MathJax-script" async
	src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

<script src="http://code.jquery.com/jquery-1.12.4.min.js"
	integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>

<script src="../docs-assets/Bigfoot.js"></script>
<link href="../docs-assets/Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Command Grammar Lines' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">if</a></li><li><a href="index.html#5">Chapter 5: Command Parser</a></li><li><b>Command Grammar Lines</b></li></ul></div>
<p class="purpose">A CG line is a list of CG tokens to specify a textual pattern. For example, "take [something] out" is a CG line of three tokens.</p>

<ul class="toc"><li><a href="5-cgl.html#SP8">&#167;8. Relevant only for CG_IS_VALUE lines</a></li><li><a href="5-cgl.html#SP9">&#167;9. Conditional lines</a></li><li><a href="5-cgl.html#SP13">&#167;13. Mistakes</a></li><li><a href="5-cgl.html#SP14">&#167;14. Single word optimisation</a></li><li><a href="5-cgl.html#SP15">&#167;15. Slashing the line</a></li><li><a href="5-cgl.html#SP16">&#167;16. Determining the line</a></li><li><a href="5-cgl.html#SP17">&#167;17. Sorting the lines in a grammar</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>CG lines can be as simple as single words, to describe an object in the
world model perhaps, or can be longer prototypes of commands to describe
actions. There are many, many examples in <a href="../standard_rules/cmgr.html" class="internal">Command Grammar (in standard_rules)</a>,
but for example in:
</p>

<blockquote>
    <p>Understand "remove [things inside] from [something]" as removing it from.</p>
</blockquote>

<p class="commentary">...the CG line "[things inside] from [something]" is added to the CG for the
command verb REMOVE. This is a CG line with a <a href="5-dt.html#SP1" class="internal">determination_type</a>
expressing that it describes two <span class="extract"><span class="extract-syntax">K_object</span></span> terms, the first perhaps being
multiple and the second not; and with <span class="extract"><span class="extract-syntax">resulting_action</span></span> set to the
removing it from action. That's a feature only seen in lines for
<span class="extract"><span class="extract-syntax">CG_IS_COMMAND</span></span> grammars, in fact.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_line</span><span class="plain-syntax">; </span><span class="comment-syntax"> linked list in creation order</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sorted_next_line</span><span class="plain-syntax">; </span><span class="comment-syntax"> and in applicability order</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">general_sort_bonus</span><span class="plain-syntax">; </span><span class="comment-syntax"> temporary values used in grammar line sorting</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">understanding_sort_bonus</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">where_grammar_specified</span><span class="plain-syntax">; </span><span class="comment-syntax"> where found in source</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">original_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> the word number of the double-quoted grammar text...</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tokens</span><span class="plain-syntax">; </span><span class="comment-syntax"> ...which is parsed into this list of tokens</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">lexeme_count</span><span class="plain-syntax">; </span><span class="comment-syntax"> number of lexemes, or </span><span class="extract"><span class="extract-syntax">-1</span></span><span class="comment-syntax"> if not yet counted</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">determination_type</span><span class="plain-syntax"> </span><span class="identifier-syntax">cgl_type</span><span class="plain-syntax">; </span><span class="comment-syntax"> only correct after determination occurs</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">understand_when_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> match me only when this condition holds</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">understand_when_prop</span><span class="plain-syntax">; </span><span class="comment-syntax"> match me only when this proposition applies</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pluralised</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_SUBJECT</span></span><span class="comment-syntax">: refers in the plural</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">action_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">resulting_action</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_COMMAND</span></span><span class="comment-syntax">: the action</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reversed</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_COMMAND</span></span><span class="comment-syntax">: the two values are in reverse order</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">mistaken</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">CG_IS_COMMAND</span></span><span class="comment-syntax">: is this understood as a mistake?</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">mistake_response_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> if so, reply thus</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg_line_compilation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">compilation_data</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure cg_line is accessed in 4/ap, 4/act, 4/as, 4/nap, 4/gng, 5/pp, 5/us, 5/cg, 5/ts, 6/db, 6/dl, 6/dc and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="function-syntax">CGLines::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">CGLines::new</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_10">&#167;19.10</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">action_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ac</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token_list</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reversed</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pluralised</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">token_list</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no token list for CGL"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Initialise listing data</span><span class="named-paragraph-number">2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_grammar_specified</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">original_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax"> = </span><span class="identifier-syntax">token_list</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax"> = -1; </span><span class="comment-syntax"> no count made as yet</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax"> = </span><a href="5-dt.html#SP2" class="function-link"><span class="function-syntax">DeterminationTypes::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understand_when_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understand_when_prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pluralised</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pluralised</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">resulting_action</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ac</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reversed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">reversed</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistaken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistake_response_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compilation_data</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RTCommandGrammarLines::new_compilation_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ac</span><span class="plain-syntax">) </span><a href="4-act.html#SP7" class="function-link"><span class="function-syntax">Actions::add_gl</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ac</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2_1" class="paragraph-anchor"></a><b>&#167;2.1. </b>A command grammar has a list of CGLs. But in fact it has two lists, with the
same contents, but in different orders. The unsorted list holds them in order
of creation; the sorted one in order of matching priority at run-time. This
sorting is a big issue: see <a href="5-cgl.html#SP17" class="internal">CGLines::list_sort</a> below.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_THROUGH_UNSORTED_CG_LINES</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_THROUGH_SORTED_CG_LINES</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_first_line</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_next_line</span><span class="plain-syntax">)</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">UNCALCULATED_BONUS</span><span class="plain-syntax"> -1000000</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialise listing data</span><span class="named-paragraph-number">2.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax"> = </span><span class="constant-syntax">UNCALCULATED_BONUS</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understanding_sort_bonus</span><span class="plain-syntax"> = </span><span class="constant-syntax">UNCALCULATED_BONUS</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>While we're talking loops... CG lines are lists of CG tokens:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_THROUGH_CG_TOKENS</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">?(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">)</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>To count how many lines a CG has so far, we use the unsorted list, since we
don't know if the sorted one has been made yet:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::list_length</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">CGLines::list_length</span></span>:<br/>Command Grammars - <a href="5-cg.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_UNSORTED_CG_LINES</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">) </span><span class="identifier-syntax">c</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>CG lines are added to a CG by being put at the end of the unsorted list.
(Once sorting has occurred, it is too late.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::list_add</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">CGLines::list_add</span></span>:<br/>Command Grammars - <a href="5-cg.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_gl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_first_line</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"too late to add lines to CG"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_gl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_gl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">posn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">posn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">) </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">posn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_gl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>In rare cases CG lines are also removed, but again, before sorting occurs.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::list_remove</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">CGLines::list_remove</span></span>:<br/>Command Grammars - <a href="5-cg.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">action_name</span><span class="plain-syntax"> *</span><span class="identifier-syntax">find</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_first_line</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"too late to remove lines from CG"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">posn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">posn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">posn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">resulting_action</span><span class="plain-syntax"> == </span><span class="identifier-syntax">find</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR_CONSTRUCTION</span><span class="plain-syntax">, </span><span class="string-syntax">"Removing grammar line: $g\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">posn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">posn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>We make no attempt to pretty-print a complete breakdown of CG, and instead
log just enough to identify which one it is:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::log</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">CGLines::log</span></span>:<br/>IF Module - <a href="1-im.html#SP2">&#167;2</a>, <a href="1-im.html#SP2_2">&#167;2.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;CGL%d:%W&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">original_text</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Relevant only for CG_IS_VALUE lines.</b>In <span class="extract"><span class="extract-syntax">CG_IS_VALUE</span></span> grammars, the lines are ways to refer to a specific value
which is not an object, and we record which value the line refers to here.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::set_single_term</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">CGLines::set_single_term</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_11">&#167;19.11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl_value</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="5-dt.html#SP4" class="function-link"><span class="function-syntax">DeterminationTypes::set_single_term</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax">), </span><span class="identifier-syntax">cgl_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Conditional lines.</b>A few grammar lines take effect only when some circumstance holds: most I7
conditions are valid to specify this, with the notation "Understand ... as
... when ...". However, we want to protect new authors from mistakes
like this:
</p>

<blockquote>
    <p>Understand "mate" as Fred when asking Fred to do something: ...</p>
</blockquote>

<p class="commentary">where the condition couldn't test anything useful because it's not yet
known what the action will be.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;understand-condition&gt;</span>
<span class="plain-syntax">    </span><span class="function-syntax">&lt;s-non-action-condition&gt;</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    </span><span class="function-syntax">&lt;s-condition&gt;</span><span class="plain-syntax"> |</span>
<span class="plain-syntax">    ...</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9_1" class="paragraph-anchor"></a><b>&#167;9.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_WhenAction problem</span><span class="named-paragraph-number">9.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_WhenAction</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="string-syntax">"the condition after 'when' involves the current action"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"but this can never work, because when Inform is still trying to "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"understand a command, the current action isn't yet decided on."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP9">&#167;9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2" class="paragraph-anchor"></a><b>&#167;9.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_BadWhen problem</span><span class="named-paragraph-number">9.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BadWhen</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="string-syntax">"the condition after 'when' makes no sense to me"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"although otherwise this worked - it is only the part after 'when' "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"which I can't follow."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP9">&#167;9</a> and <a href="5-cgl.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>Such CGLs have an "understand when" text. We have to keep this as text and
typecheck it with Dash only when it will actually be used; this is where
that happens.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::set_understand_when</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">CGLines::set_understand_when</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_10">&#167;19.10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understand_when_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">CGLines::get_understand_cond</span><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understand_when_text</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_grammar_specified</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;understand-condition&gt;(cgl-&gt;</span><span class="element-syntax">understand_when_text</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Dash::validate_conditional_clause</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP9_2" class="named-paragraph-link"><span class="named-paragraph">Issue PM_BadWhen problem</span><span class="named-paragraph-number">9.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">spec</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>More subtly, a CGL might be given as a way to describe, say, "an open door".
This will go into the CG associated with the kind <span class="extract"><span class="extract-syntax">K_door</span></span>, but the line will
have the proposition \({\it open}(x)\) attached to it: the description then
matches an object \(x\) only when this proposition holds. (It must always be
a proposition with a single free variable.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::set_understand_prop</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">CGLines::set_understand_prop</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_10">&#167;19.10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understand_when_prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prop</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>Use of either feature makes a CGL "conditional":
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::conditional</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">CGLines::conditional</span></span>:<br/><a href="5-cgl.html#SP14">&#167;14</a>, <a href="5-cgl.html#SP19_8">&#167;19.8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understand_when_text</span><span class="plain-syntax">)) || (</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understand_when_prop</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Mistakes.</b>These are grammar lines used in command CGs for commands which are accepted
but only in order to print nicely worded rejections.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::set_mistake</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">CGLines::set_mistake</span></span>:<br/>Understand Sentences - <a href="5-us.html#SP19_10">&#167;19.10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">MW</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistaken</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistake_response_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MW</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Single word optimisation.</b>The grammars used to parse names of objects are normally compiled into
<span class="extract"><span class="extract-syntax">parse_name</span></span> routines. But the I6 parser also uses the <span class="extract"><span class="extract-syntax">name</span></span> property,
and it is advantageous to squeeze as much as possible into <span class="extract"><span class="extract-syntax">name</span></span> and
as little as possible into <span class="extract"><span class="extract-syntax">parse_name</span></span>. The only possible candidates
for that are grammar lines consisting of single unconditional words, as
detected by the following function:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::cgl_contains_single_unconditional_word</span><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        &amp;&amp; (</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        &amp;&amp; (</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        &amp;&amp; (</span><a href="5-cgt.html#SP9" class="function-link"><span class="function-syntax">CGTokens::is_literal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        &amp;&amp; (</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pluralised</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        &amp;&amp; (</span><a href="5-cgl.html#SP12" class="function-link"><span class="function-syntax">CGLines::conditional</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><a href="5-cgt.html#SP8" class="function-link"><span class="function-syntax">CGTokens::text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Slashing the line.</b>Slashing is the process of dealing with forward slash tokens in a CG line.
It's done one line at a time, each line being independent of all others for
this purpose, so:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::slash</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">CGLines::slash</span></span>:<br/>Command Grammars - <a href="5-cg.html#SP19">&#167;19</a><br/>Command Grammar Tokens - <a href="5-cgt.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_UNSORTED_CG_LINES</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_grammar_specified</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP15_1" class="named-paragraph-link"><span class="named-paragraph">Annotate the CG tokens with slash-class and slash-dash-dash</span><span class="named-paragraph-number">15.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP15_2" class="named-paragraph-link"><span class="named-paragraph">Throw a problem if slash has been used with non-literal tokens</span><span class="named-paragraph-number">15.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP15_3" class="named-paragraph-link"><span class="named-paragraph">Calculate the lexeme count</span><span class="named-paragraph-number">15.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> != </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> != </span><span class="constant-syntax">CG_IS_TOKEN</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP15_4" class="named-paragraph-link"><span class="named-paragraph">Disallow a potentially empty line</span><span class="named-paragraph-number">15.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15_1" class="paragraph-anchor"></a><b>&#167;15.1. </b>The tokenised text of a CG line can contain "slashes":
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">given</span><span class="plain-syntax"> </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">Inform</span><span class="plain-syntax"> </span><span class="identifier-syntax">source</span><span class="plain-syntax"> </span><span class="identifier-syntax">text</span><span class="plain-syntax">   </span><span class="string-syntax">"take up/in all washing/laundry/linen"</span>
<span class="identifier-syntax">tokenised</span><span class="plain-syntax">                     </span><span class="identifier-syntax">take</span><span class="plain-syntax"> </span><span class="identifier-syntax">up</span><span class="plain-syntax"> / </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">all</span><span class="plain-syntax"> </span><span class="identifier-syntax">washing</span><span class="plain-syntax"> / </span><span class="identifier-syntax">laundry</span><span class="plain-syntax"> / </span><span class="identifier-syntax">linen</span>
</pre>
<p class="commentary">This is a run of 10 CG tokens, three of them forward slashes which are actually
markers to indicate disjunction: thus the three tokens "up / all" intend to
match just one word of the player's command, which can be either UP or ALL.
</p>

<p class="commentary">Slashing consolidates this line to 7 CG tokens, giving each one a <span class="extract"><span class="extract-syntax">slash_class</span></span>
value to show which group it belongs to. 0 means that a token is not part of a
slashed group; otherwise, the group number should be shared by all the tokens
in the group, and should be different from that of other groups. Thus:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">                     </span><span class="identifier-syntax">take</span><span class="plain-syntax"> </span><span class="identifier-syntax">up</span><span class="plain-syntax"> </span><span class="identifier-syntax">in</span><span class="plain-syntax"> </span><span class="identifier-syntax">all</span><span class="plain-syntax"> </span><span class="identifier-syntax">washing</span><span class="plain-syntax"> </span><span class="identifier-syntax">laundry</span><span class="plain-syntax"> </span><span class="identifier-syntax">linen</span>
<span class="identifier-syntax">slash_class</span><span class="plain-syntax">          </span><span class="constant-syntax">0</span><span class="plain-syntax">    </span><span class="constant-syntax">1</span><span class="plain-syntax">  </span><span class="constant-syntax">1</span><span class="plain-syntax">  </span><span class="constant-syntax">0</span><span class="plain-syntax">   </span><span class="constant-syntax">2</span><span class="plain-syntax">       </span><span class="constant-syntax">2</span><span class="plain-syntax">       </span><span class="constant-syntax">2</span>
</pre>
<p class="commentary">In addition, Inform allows the syntax <span class="extract"><span class="extract-syntax">--</span></span> to mean the empty word, or rather,
to mean that it is permissible for the player's command to miss this word out.
If one option in a group is <span class="extract"><span class="extract-syntax">--</span></span> then this does not get a token of its own,
but instead results in the <span class="extract"><span class="extract-syntax">slash_dash_dash</span></span> field to be set. For example,
consider "near --/the/that tree/shrub":
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">                       </span><span class="identifier-syntax">near</span><span class="plain-syntax">  </span><span class="identifier-syntax">the</span><span class="plain-syntax">  </span><span class="identifier-syntax">that</span><span class="plain-syntax">  </span><span class="identifier-syntax">tree</span><span class="plain-syntax">  </span><span class="identifier-syntax">shrub</span>
<span class="identifier-syntax">slash_class</span><span class="plain-syntax">            </span><span class="constant-syntax">0</span><span class="plain-syntax">     </span><span class="constant-syntax">1</span><span class="plain-syntax">    </span><span class="constant-syntax">1</span><span class="plain-syntax">     </span><span class="constant-syntax">2</span><span class="plain-syntax">     </span><span class="constant-syntax">2</span>
<span class="identifier-syntax">slash_dash_dash</span><span class="plain-syntax">        </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span>
</pre>
<p class="commentary">Note that <span class="extract"><span class="extract-syntax">--</span></span> occurring on its own, outside of a run of slashes, has by
definition no effect, and disappears without trace in this process.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Annotate the CG tokens with slash-class and slash-dash-dash</span><span class="named-paragraph-number">15.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_CG_TOKENS</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">alternatives_group</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">class_start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_CG_TOKENS</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><a href="5-cgt.html#SP8" class="function-link"><span class="function-syntax">CGTokens::text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">)) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><a href="5-cgt.html#SP8" class="function-link"><span class="function-syntax">CGTokens::text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">))) ==</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">FORWARDSLASH_V</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">class_start</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">; </span><span class="identifier-syntax">alternatives_group</span><span class="plain-syntax">++; </span><span class="comment-syntax"> start new equiv class</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">class_start</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_dash_dash</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alternatives_group</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> = </span><span class="identifier-syntax">alternatives_group</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><a href="5-cgt.html#SP8" class="function-link"><span class="function-syntax">CGTokens::text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">)) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><a href="5-cgt.html#SP8" class="function-link"><span class="function-syntax">CGTokens::text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">))) ==</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">DOUBLEDASH_V</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">class_start</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_dash_dash</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">; </span><span class="comment-syntax"> excise both</span>
<span class="plain-syntax">            } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">; </span><span class="comment-syntax"> excise slash</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP15">&#167;15</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP15_2" class="paragraph-anchor"></a><b>&#167;15.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Throw a problem if slash has been used with non-literal tokens</span><span class="named-paragraph-number">15.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_CG_TOKENS</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><a href="5-cgt.html#SP9" class="function-link"><span class="function-syntax">CGTokens::is_literal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OverAmbitiousSlash</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="string-syntax">"the slash '/' can only be used between single literal words"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"so 'underneath/under/beneath' is allowed but 'beneath/[florid "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"ways to say under]/under' isn't."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP15">&#167;15</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP15_3" class="paragraph-anchor"></a><b>&#167;15.3. </b>It is now easy to count the number of "lexemes", that's to say, the number
of groups arising from the calculations just done. In this example there are 4:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">                     </span><span class="identifier-syntax">take</span><span class="plain-syntax">   </span><span class="identifier-syntax">up</span><span class="plain-syntax"> </span><span class="identifier-syntax">in</span><span class="plain-syntax">   </span><span class="identifier-syntax">all</span><span class="plain-syntax">   </span><span class="identifier-syntax">washing</span><span class="plain-syntax"> </span><span class="identifier-syntax">laundry</span><span class="plain-syntax"> </span><span class="identifier-syntax">linen</span>
<span class="identifier-syntax">slash_class</span><span class="plain-syntax">          </span><span class="constant-syntax">0</span><span class="plain-syntax">      </span><span class="constant-syntax">1</span><span class="plain-syntax">  </span><span class="constant-syntax">1</span><span class="plain-syntax">    </span><span class="constant-syntax">0</span><span class="plain-syntax">     </span><span class="constant-syntax">2</span><span class="plain-syntax">       </span><span class="constant-syntax">2</span><span class="plain-syntax">       </span><span class="constant-syntax">2</span>
<span class="identifier-syntax">lexemes</span><span class="plain-syntax">              +--+   +---+   +-+   +-------------------+</span>
</pre>
<p class="commentary">And in this one 3:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">                     </span><span class="identifier-syntax">near</span><span class="plain-syntax">   </span><span class="identifier-syntax">the</span><span class="plain-syntax">  </span><span class="identifier-syntax">that</span><span class="plain-syntax">   </span><span class="identifier-syntax">tree</span><span class="plain-syntax">  </span><span class="identifier-syntax">shrub</span>
<span class="identifier-syntax">slash_class</span><span class="plain-syntax">          </span><span class="constant-syntax">0</span><span class="plain-syntax">      </span><span class="constant-syntax">1</span><span class="plain-syntax">    </span><span class="constant-syntax">1</span><span class="plain-syntax">      </span><span class="constant-syntax">2</span><span class="plain-syntax">     </span><span class="constant-syntax">2</span>
<span class="identifier-syntax">lexemes</span><span class="plain-syntax">              +--+   +-------+   +---------+</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate the lexeme count</span><span class="named-paragraph-number">15.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_CG_TOKENS</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> == </span><span class="identifier-syntax">i</span><span class="plain-syntax">))</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP15">&#167;15</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP15_4" class="paragraph-anchor"></a><b>&#167;15.4. </b>The following catches grammar such as:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">Understand</span><span class="plain-syntax"> </span><span class="string-syntax">"Prof/--"</span><span class="plain-syntax"> </span><span class="identifier-syntax">as</span><span class="plain-syntax"> </span><span class="identifier-syntax">Professor</span><span class="plain-syntax"> </span><span class="identifier-syntax">Zaphier</span><span class="plain-syntax">.</span>
</pre>
<p class="commentary">which would otherwise compile fine, but lead to a hang of the story file when
attempting to recognise Zaphier's name.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Disallow a potentially empty line</span><span class="named-paragraph-number">15.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">possibly_empty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_CG_TOKENS</span><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">possibly_empty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dashdashed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_dash_dash</span><span class="plain-syntax">) </span><span class="identifier-syntax">dashdashed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">                    (</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> == </span><span class="identifier-syntax">i</span><span class="plain-syntax">)) </span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dashdashed</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">possibly_empty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">possibly_empty</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EmptyUnderstandLine</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"the optional '--' word has been used here in such a way that it "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"would be possible for a completely empty phrase to be understood "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"in this context"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"but that isn't allowed."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP15">&#167;15</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Determining the line.</b>Here the aim is to find the <a href="5-dt.html#SP1" class="internal">determination_type</a> of a CGL. Sneakily, though,
we also take the opportunity to calculate its two "sorting bonuses", which
affect how the list will be arranged when it is compiled.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">CGL_SCORE_TOKEN_RANGE</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CGL_SCORE_BUMP</span><span class="plain-syntax"> (</span><span class="constant-syntax">CGL_SCORE_TOKEN_RANGE</span><span class="plain-syntax">*</span><span class="constant-syntax">CGL_SCORE_TOKEN_RANGE</span><span class="plain-syntax">)</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::cgl_determine</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">CGLines::cgl_determine</span></span>:<br/>Command Grammars - <a href="5-cg.html#SP20">&#167;20</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR_CONSTRUCTION</span><span class="plain-syntax">, </span><span class="string-syntax">"Determining $g\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">where_grammar_specified</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understanding_sort_bonus</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">; </span><span class="comment-syntax"> start from first token...</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="5-cg.html#SP5" class="function-link"><span class="function-syntax">CommandGrammars::cg_is_genuinely_verbal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">first</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">first</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">; </span><span class="comment-syntax"> ...unless it's in a nonempty command verb grammar</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">line_length</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) </span><span class="identifier-syntax">line_length</span><span class="plain-syntax">++;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">multiples</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP16_1" class="named-paragraph-link"><span class="named-paragraph">Make the actual calculations</span><span class="named-paragraph-number">16.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP16_2" class="named-paragraph-link"><span class="named-paragraph">Check for a variety of problems</span><span class="named-paragraph-number">16.2</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Log::aspect_switched_on</span><span class="plain-syntax">(</span><span class="constant-syntax">GRAMMAR_CONSTRUCTION_DA</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"dt = "</span><span class="plain-syntax">); </span><a href="5-dt.html#SP1" class="function-link"><span class="function-syntax">DeterminationTypes::log</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">", lexeme count %d, sort bonus %d, understanding sort bonus %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understanding_sort_bonus</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16_1" class="paragraph-anchor"></a><b>&#167;16.1. </b>The general sort bonus is \(Rs_0 + s_1\), where \(R\) is the <span class="extract"><span class="extract-syntax">CGL_SCORE_TOKEN_RANGE</span></span>
and \(s_0\), \(s_1\) are the scores for the first and second tokens describing values,
which are such that \(0\leq s_i&lt;R\); or if none of the \(n\) tokens describes a value,
the GSB is \(R^2n\), which is guaranteed to be much larger.
</p>

<p class="commentary">However, there is also an understanding sort bonus, which is really a penalty
incurred by "[text]" tokens &mdash; which are very free-form topics of conversation.
A "[text]" at token position \(i\), where \(0\leq i&lt;n\), scores \(R^2(i-R^2) + (n - 1 - i)\).
Given that \(i\) is small and \(R^2\) is big, this is basically a huge negative
number, but is such that a "[text]" earlier in the line is penalised just a
little bit more than a "[text]" later.
</p>

<p class="commentary">For \(R=10\), the following might thus happen. (I've simplified this table by
having the individual tokens all score 1, but in fact they can score a range
of small numbers: see <a href="5-cgt.html#SP15" class="internal">CGTokens::score_bonus</a>.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">                        </span><span class="identifier-syntax">n</span><span class="plain-syntax">       </span><span class="identifier-syntax">s_0</span><span class="plain-syntax">     </span><span class="identifier-syntax">s_1</span><span class="plain-syntax">     </span><span class="identifier-syntax">gsb</span><span class="plain-syntax">     </span><span class="identifier-syntax">usb</span>
<span class="identifier-syntax">inventory</span><span class="plain-syntax">               </span><span class="constant-syntax">1</span><span class="plain-syntax">       --      --      </span><span class="constant-syntax">100</span><span class="plain-syntax">     </span><span class="constant-syntax">0</span>
<span class="plain-syntax">[</span><span class="identifier-syntax">thing</span><span class="plain-syntax">]                 </span><span class="constant-syntax">1</span><span class="plain-syntax">       </span><span class="constant-syntax">1</span><span class="plain-syntax">       --      </span><span class="constant-syntax">10</span><span class="plain-syntax">      </span><span class="constant-syntax">0</span>
<span class="plain-syntax">[</span><span class="identifier-syntax">thing</span><span class="plain-syntax">] </span><span class="identifier-syntax">from</span><span class="plain-syntax"> [</span><span class="identifier-syntax">thing</span><span class="plain-syntax">]    </span><span class="constant-syntax">3</span><span class="plain-syntax">       </span><span class="constant-syntax">1</span><span class="plain-syntax">       </span><span class="constant-syntax">1</span><span class="plain-syntax">       </span><span class="constant-syntax">11</span><span class="plain-syntax">      </span><span class="constant-syntax">0</span>
<span class="identifier-syntax">umbrage</span><span class="plain-syntax"> </span><span class="identifier-syntax">over</span><span class="plain-syntax"> [</span><span class="identifier-syntax">text</span><span class="plain-syntax">]     </span><span class="constant-syntax">3</span><span class="plain-syntax">       </span><span class="constant-syntax">1</span><span class="plain-syntax">       --      </span><span class="constant-syntax">10</span><span class="plain-syntax">      -9800</span>
<span class="identifier-syntax">umbrage</span><span class="plain-syntax"> [</span><span class="identifier-syntax">text</span><span class="plain-syntax">]          </span><span class="constant-syntax">2</span><span class="plain-syntax">       </span><span class="constant-syntax">1</span><span class="plain-syntax">       --      </span><span class="constant-syntax">10</span><span class="plain-syntax">      -9900</span>
<span class="identifier-syntax">umbrage</span><span class="plain-syntax"> [</span><span class="identifier-syntax">text</span><span class="plain-syntax">] </span><span class="identifier-syntax">issue</span><span class="plain-syntax">    </span><span class="constant-syntax">3</span><span class="plain-syntax">       </span><span class="constant-syntax">1</span><span class="plain-syntax">       --      </span><span class="constant-syntax">10</span><span class="plain-syntax">      -9899</span>
</pre>
<p class="commentary">It is roughly true that if we sort these lines in descending order of the
sum of those scores, they come out in the order we need to try them when
parsing the player's command at run-time. For the exact sorting rules, see below.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make the actual calculations</span><span class="named-paragraph-number">16.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nulls_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><a href="5-cgt.html#SP14" class="function-link"><span class="function-syntax">CGTokens::determine</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">score</span><span class="plain-syntax"> = </span><a href="5-cgt.html#SP15" class="function-link"><span class="function-syntax">CGTokens::score_bonus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">score</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">score</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">CGL_SCORE_TOKEN_RANGE</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"token score out of range"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">GRAMMAR_CONSTRUCTION</span><span class="plain-syntax">, </span><span class="string-syntax">"token %d/%d: &lt;%W&gt; --&gt; $P (score %d)\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">pos</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">line_length</span><span class="plain-syntax">, </span><a href="5-cgt.html#SP8" class="function-link"><span class="function-syntax">CGTokens::text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">), </span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">score</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP16_1_1" class="named-paragraph-link"><span class="named-paragraph">Text tokens contribute also to the understanding sort bonus</span><span class="named-paragraph-number">16.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">score_multiplier</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dt.html#SP1" class="function-link"><span class="function-syntax">DeterminationTypes::get_no_values_described</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax">)) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">score_multiplier</span><span class="plain-syntax"> = </span><span class="constant-syntax">CGL_SCORE_TOKEN_RANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><a href="5-dt.html#SP3" class="function-link"><span class="function-syntax">DeterminationTypes::add_term</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax">), </span><span class="identifier-syntax">spec</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><a href="5-cgt.html#SP10" class="function-link"><span class="function-syntax">CGTokens::is_multiple</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax"> += </span><span class="identifier-syntax">score</span><span class="plain-syntax">*</span><span class="identifier-syntax">score_multiplier</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">nulls_count</span><span class="plain-syntax">++;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-cgt.html#SP10" class="function-link"><span class="function-syntax">CGTokens::is_multiple</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">)) </span><span class="identifier-syntax">multiples</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pos</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nulls_count</span><span class="plain-syntax"> == </span><span class="identifier-syntax">line_length</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax"> = </span><span class="constant-syntax">CGL_SCORE_BUMP</span><span class="plain-syntax">*</span><span class="identifier-syntax">nulls_count</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP16">&#167;16</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_1_1" class="paragraph-anchor"></a><b>&#167;16.1.1. </b>This looks for a "[text]" token, which is the Inform syntax to mean one
which parses to a <span class="extract"><span class="extract-syntax">K_understanding</span></span> match.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Text tokens contribute also to the understanding sort bonus</span><span class="named-paragraph-number">16.1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Specifications::is_kind_like</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Specifications::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">))) { </span><span class="comment-syntax"> "[text]" token</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">usb_contribution</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> - </span><span class="constant-syntax">CGL_SCORE_BUMP</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">usb_contribution</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">usb_contribution</span><span class="plain-syntax"> = -1; </span><span class="comment-syntax"> very unlikely to happen</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">usb_contribution</span><span class="plain-syntax"> = </span><span class="constant-syntax">CGL_SCORE_BUMP</span><span class="plain-syntax">*</span><span class="identifier-syntax">usb_contribution</span><span class="plain-syntax"> + (</span><span class="identifier-syntax">line_length</span><span class="plain-syntax">-1-</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understanding_sort_bonus</span><span class="plain-syntax"> += </span><span class="identifier-syntax">usb_contribution</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP16_1">&#167;16.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16_2" class="paragraph-anchor"></a><b>&#167;16.2. </b>If none of these problems occurs, then the grammar can legally be compiled.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check for a variety of problems</span><span class="named-paragraph-number">16.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">multiples</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MultipleMultiples</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"there can be at most one token in any line which can match multiple things"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"so you'll have to remove one of the 'things' tokens and make it a 'something' "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"instead."</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> != </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><a href="5-dt.html#SP1" class="function-link"><span class="function-syntax">DeterminationTypes::get_no_values_described</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax">)) &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TwoValuedToken</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"there can be at most one varying part in the definition of a named token"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"so 'Understand \"button [a number]\" as \"[button indication]\"' is allowed "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"but 'Understand \"button [a number] on [something]\" as \"[button "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"indication]\"' is not."</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reversed</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><a href="5-dt.html#SP1" class="function-link"><span class="function-syntax">DeterminationTypes::get_no_values_described</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax">)) &lt; </span><span class="constant-syntax">2</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_CantReverseOne</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"you can't use a 'reversed' action when you supply fewer than two values for "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"it to apply to"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"since reversal is the process of exchanging them."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">slash_class</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><a href="5-cg.html#SP5" class="function-link"><span class="function-syntax">CommandGrammars::cg_is_genuinely_verbal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_SlashedCommand</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"at present you're not allowed to use a / between command words at the "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"start of a line"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"so 'put/interpose/insert [something]' is out."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">; </span><span class="identifier-syntax">cgt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="5-cgt.html#SP9" class="function-link"><span class="function-syntax">CGTokens::is_topic</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><a href="5-cgt.html#SP9" class="function-link"><span class="function-syntax">CGTokens::is_literal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TextFollowedBy</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="string-syntax">"a '[text]' token must either match the end of some text, or be followed "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"by definitely known wording"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"since otherwise the run-time parser isn't good enough to make sense of "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"things."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">token_relation</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> != </span><span class="constant-syntax">CG_IS_SUBJECT</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_GrammarObjectlessRelation</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="string-syntax">"a grammar token in an 'Understand...' can only be based on a relation if it "</span>
<span class="plain-syntax">                </span><span class="string-syntax">"is to understand the name of a room or thing"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="string-syntax">"since otherwise there is nothing for the relation to be with."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax"> == </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">token_values</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token_value_kinds</span><span class="plain-syntax">[2];</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;2; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">token_value_kinds</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">cg_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens</span><span class="plain-syntax">; </span><span class="identifier-syntax">token</span><span class="plain-syntax">; </span><span class="identifier-syntax">token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">token</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_token</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">code_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">) </span><span class="identifier-syntax">code_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">consult_mode</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_CONSULT</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="5-cgt.html#SP16" class="function-link"><span class="function-syntax">CGTokens::verify_and_find_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">token</span><span class="plain-syntax">, </span><span class="identifier-syntax">code_mode</span><span class="plain-syntax">, </span><span class="identifier-syntax">consult_mode</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">token_values</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"too many value-producing tokens"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">token_value_kinds</span><span class="plain-syntax">[</span><span class="identifier-syntax">token_values</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reversed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">swap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">token_value_kinds</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">token_value_kinds</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">token_value_kinds</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">token_value_kinds</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">swap</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax"> == </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistaken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax">                </span><a href="4-as.html#SP5" class="function-link"><span class="function-syntax">ActionSemantics::check_valid_application</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">resulting_action</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">token_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">token_value_kinds</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP16">&#167;16</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Sorting the lines in a grammar.</b>The CGLs in a grammar are insertion sorted into a sorted version. This is not
the controversial part: <a href="5-cgl.html#SP19" class="internal">CGLines::cg_line_must_precede</a> is the part
people argued over for years.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="function-syntax">CGLines::list_sort</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">CGLines::list_sort</span></span>:<br/>Command Grammars - <a href="5-cg.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">unsorted_head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unsorted_head</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sorted_head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unsorted_head</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sorted_head</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unsorted_head</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">cgl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sorted_head</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-cgl.html#SP19" class="function-link"><span class="function-syntax">CGLines::cg_line_must_precede</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl2</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">sorted_head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cgl2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgl3</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">cgl2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_next_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cgl2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">cgl3</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-cgl.html#SP19" class="function-link"><span class="function-syntax">CGLines::cg_line_must_precede</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">, </span><span class="identifier-syntax">cgl2</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">cgl3</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">cgl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorted_next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cgl2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">sorted_head</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>As noted, the following function was responsible for quite some debate in
the early days of Inform 7. The issue here is that the command parser at
run-time accepts the first match it can make, when given a list of options.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>
Because of that, it is essential to put these options in the right order, or
some can never happen. For example,
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">ask</span><span class="plain-syntax"> [</span><span class="identifier-syntax">someone</span><span class="plain-syntax">] </span><span class="identifier-syntax">about</span><span class="plain-syntax"> [</span><span class="identifier-syntax">something</span><span class="plain-syntax">]</span>
<span class="identifier-syntax">ask</span><span class="plain-syntax"> [</span><span class="identifier-syntax">someone</span><span class="plain-syntax">] </span><span class="identifier-syntax">about</span><span class="plain-syntax"> [</span><span class="identifier-syntax">text</span><span class="plain-syntax">]</span>
</pre>
<p class="commentary">have to be that way around, because any command which matches the first line
here also matches the second. Putting these lines into order used to be part
of the craft of the Inform 6 programmer, but it was always difficult to do,
and Inform 7 aimed to liberate authors from the need to do this. A long
period of aggrieved bug-reporting followed, when it turned out that Inform 7
made different decisions than authors accustomed to Inform 6 would like.
We ended up with the following algorithm, which has not changed since at
least 2010, and will not change again.
</p>

<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> Well... roughly. See <a href="../CommandParserKit/prsr.html" class="internal">Parser (in CommandParserKit)</a> for the gory details.
<a href="#fnref:1" title="return to text"> &#x21A9;</a></p></li></ul>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b>The code in <a href="5-cgl.html#SP16" class="internal">CGLines::cgl_determine</a> looked as if we would decide
if line <span class="extract"><span class="extract-syntax">L1</span></span> precedes <span class="extract"><span class="extract-syntax">L2</span></span> by adding up their score bonuses, and letting the
higher scorer go first. That is in fact nearly equivalent to the following,
but not quite.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">CGLines::cg_line_must_precede</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">CGLines::cg_line_must_precede</span></span>:<br/><a href="5-cgl.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">command_grammar</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cg</span><span class="plain-syntax">, </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L1</span><span class="plain-syntax">, </span><span class="reserved-syntax">cg_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_1" class="named-paragraph-link"><span class="named-paragraph">Perform some sanity checks</span><span class="named-paragraph-number">19.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_2" class="named-paragraph-link"><span class="named-paragraph">Nothing precedes itself</span><span class="named-paragraph-number">19.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_3" class="named-paragraph-link"><span class="named-paragraph">Lower understanding penalties precede higher ones</span><span class="named-paragraph-number">19.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_4" class="named-paragraph-link"><span class="named-paragraph">Shorter precedes longer in command verbs, longer precedes shorter otherwise</span><span class="named-paragraph-number">19.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_5" class="named-paragraph-link"><span class="named-paragraph">Mistakes precede correct readings</span><span class="named-paragraph-number">19.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_6" class="named-paragraph-link"><span class="named-paragraph">Higher sort bonuses precede lower ones</span><span class="named-paragraph-number">19.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_7" class="named-paragraph-link"><span class="named-paragraph">More specific determinations precede less specific ones</span><span class="named-paragraph-number">19.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_8" class="named-paragraph-link"><span class="named-paragraph">Conditional readings precede unconditional readings</span><span class="named-paragraph-number">19.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cgl.html#SP19_9" class="named-paragraph-link"><span class="named-paragraph">Lines created earlier precede lines created later in the source text</span><span class="named-paragraph-number">19.9</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19_1" class="paragraph-anchor"></a><b>&#167;19.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Perform some sanity checks</span><span class="named-paragraph-number">19.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">L1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">L2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to sort null CGLs"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax"> == -1) || (</span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax"> == -1))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to sort unslashed CGLs"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax"> == </span><span class="constant-syntax">UNCALCULATED_BONUS</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax"> == </span><span class="constant-syntax">UNCALCULATED_BONUS</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to sort uncalculated CGLs"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_2" class="paragraph-anchor"></a><b>&#167;19.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Nothing precedes itself</span><span class="named-paragraph-number">19.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">L2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_3" class="paragraph-anchor"></a><b>&#167;19.3. </b>"[text]" tokens have such an extreme effect that they are the first thing
to look at. The following guarantees that any line without "[text]" tokens
always precedes any line with them: see the calculation of the USB above.
</p>

<p class="commentary">Thus <span class="extract"><span class="extract-syntax">"read chapter [text]"</span></span> precedes <span class="extract"><span class="extract-syntax">"read [text]"</span></span> precedes <span class="extract"><span class="extract-syntax">"read [something]"</span></span>.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Lower understanding penalties precede higher ones</span><span class="named-paragraph-number">19.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understanding_sort_bonus</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understanding_sort_bonus</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understanding_sort_bonus</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">understanding_sort_bonus</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_4" class="paragraph-anchor"></a><b>&#167;19.4. </b>It seems reasonable that the length of the CG line (in lexemes, not tokens)
might be a sorting criterion, but what we do looks asymmetric. Why should
CG_IS_COMMAND grammars have the opposite convention from all others?
</p>

<p class="commentary">This arises because the command parser we use at run time works that way. The
difference is that when the parser is working on an entire command &mdash; thus,
working through a <span class="extract"><span class="extract-syntax">CG_IS_COMMAND</span></span> grammar &mdash; it always knows how many words
it has to match. If the player has typed TAKE FROG FROM AQUARIUM, the parser
has to make sense of all of the words. It needs to consider the possibility
"take [something]" before "take [something] from [something]" because there
might be an object called "frog from aquarium".
</p>

<p class="commentary">On the other hand, if it is parsing a <span class="extract"><span class="extract-syntax">CG_IS_TOKEN</span></span> grammar, it is trying to
match as many words as possible from a stream of words that will probably then
continue. It is therefore important to try to match WATERY CASCADE EFFECT
before WATERY CASCADE when looking at text like WATERY CASCADE EFFECT
IMPRESSES PEOPLE, so that we match three words not two. So in these
situations, longer possibilities must be tried first.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Shorter precedes longer in command verbs, longer precedes shorter otherwise</span><span class="named-paragraph-number">19.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cg</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cg_is</span><span class="plain-syntax"> == </span><span class="constant-syntax">CG_IS_COMMAND</span><span class="plain-syntax">) { </span><span class="comment-syntax"> command grammar: shorter beats longer</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="comment-syntax"> all other grammars: longer beats shorter</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lexeme_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_5" class="paragraph-anchor"></a><b>&#167;19.5. </b>Throughout 2006, the rule that mistakes beat non-mistakes was in fact the
most important, taking priority over length or understanding sort bonus.
This seemed logical that since mistakes were exceptional cases, they would be
better checked earlier before moving on to general cases. However, an
example provided by Eric Eve showed that although this was logically correct,
the run-time command parser would try to auto-complete lengthy mistakes and
thus fail to check subsequent commands.
</p>

<p class="commentary">For this reason, <span class="extract"><span class="extract-syntax">"look behind [something]"</span></span> as a mistake needs to be checked
after <span class="extract"><span class="extract-syntax">"look"</span></span>, or else the command parser will respond to LOOK by replying
"What do you want to look behind?" &mdash; and then saying that you are mistaken.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Mistakes precede correct readings</span><span class="named-paragraph-number">19.5</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistaken</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistaken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistaken</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">mistaken</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_6" class="paragraph-anchor"></a><b>&#167;19.6. </b>This next rule is a lexeme-based tiebreaker. We only get here if there
are the same number of lexemes in the two CGLs being compared. Lines in which
all tokens are literal words, like "tossed egg salad", are scored so highly
that they will always come first: see <a href="5-cgl.html#SP16" class="internal">CGLines::cgl_determine</a>.
But if one of the tokens is not literal, then we score it in such a way that
the specificity of the tokens is what decides. The first token is more important
than the second, and a more specific token comes before a lower one.
</p>

<p class="commentary">See <a href="5-cgt.html#SP14" class="internal">CGTokens::determine</a> for how the score of an individual token
is worked out.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Higher sort bonuses precede lower ones</span><span class="named-paragraph-number">19.6</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">general_sort_bonus</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_7" class="paragraph-anchor"></a><b>&#167;19.7. </b>By now the lines are extremely similar, but for example we might have
"put [thing] in [container]" and "put [thing] in [thing]". The first must
precede the second because <span class="extract"><span class="extract-syntax">K_container</span></span> is a subkind of <span class="extract"><span class="extract-syntax">K_thing</span></span>.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">More specific determinations precede less specific ones</span><span class="named-paragraph-number">19.7</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cs</span><span class="plain-syntax"> = </span><a href="5-dt.html#SP5" class="function-link"><span class="function-syntax">DeterminationTypes::must_precede</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax">), &amp;(</span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cgl_type</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cs</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cs</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_8" class="paragraph-anchor"></a><b>&#167;19.8. </b>The motivation for this one is similar to the case of "when" clauses for
rules in rulebooks: it ensures that a match of <span class="extract"><span class="extract-syntax">"draw [thing]"</span></span> when some
condition holds beats a match of <span class="extract"><span class="extract-syntax">"draw [thing]"</span></span> at any time, and this is
necessary under the strict superset principle.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Conditional readings precede unconditional readings</span><span class="named-paragraph-number">19.8</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="5-cgl.html#SP12" class="function-link"><span class="function-syntax">CGLines::conditional</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L1</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">        (</span><a href="5-cgl.html#SP12" class="function-link"><span class="function-syntax">CGLines::conditional</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L2</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="5-cgl.html#SP12" class="function-link"><span class="function-syntax">CGLines::conditional</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L1</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><a href="5-cgl.html#SP12" class="function-link"><span class="function-syntax">CGLines::conditional</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L2</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_9" class="paragraph-anchor"></a><b>&#167;19.9. </b>Getting down to here looks difficult, given the number of things about <span class="extract"><span class="extract-syntax">L1</span></span>
and <span class="extract"><span class="extract-syntax">L2</span></span> which have to match up &mdash; same USB, GSB, number of lexemes,
number of resulting types, equivalent resulting types, same mistake and
conditional status &mdash; but in fact it isn't all that uncommon. Equivalent pairs
produced by the Standard Rules include:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">get</span><span class="plain-syntax"> </span><span class="identifier-syntax">off</span><span class="plain-syntax"> [</span><span class="identifier-syntax">something</span><span class="plain-syntax">]</span>
<span class="identifier-syntax">get</span><span class="plain-syntax"> </span><span class="identifier-syntax">in</span><span class="plain-syntax">/</span><span class="identifier-syntax">into</span><span class="plain-syntax">/</span><span class="identifier-syntax">on</span><span class="plain-syntax">/</span><span class="identifier-syntax">onto</span><span class="plain-syntax"> [</span><span class="identifier-syntax">something</span><span class="plain-syntax">]</span>

<span class="identifier-syntax">turn</span><span class="plain-syntax"> </span><span class="identifier-syntax">on</span><span class="plain-syntax"> [</span><span class="identifier-syntax">something</span><span class="plain-syntax">]</span>
<span class="identifier-syntax">turn</span><span class="plain-syntax"> [</span><span class="identifier-syntax">something</span><span class="plain-syntax">] </span><span class="identifier-syntax">on</span>
</pre>
<p class="commentary">Only the second of these pairs leads to ambiguity, and even then only if
an object has a name like ON VISION ON &mdash; perhaps a book about the antique
BBC children's television programme "Vision On" &mdash; so that the command
TURN ON VISION ON would match both of the alternative CGLs.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Lines created earlier precede lines created later in the source text</span><span class="named-paragraph-number">19.9</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L1</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">L2</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cgl.html#SP19">&#167;19</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="5-cg.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresschapter"><a href="2-bd.html">2</a></li><li class="progresschapter"><a href="3-sm.html">3</a></li><li class="progresschapter"><a href="4-ap.html">4</a></li><li class="progresscurrentchapter">5</li><li class="progresssection"><a href="5-pp.html">pp</a></li><li class="progresssection"><a href="5-us.html">us</a></li><li class="progresssection"><a href="5-cg.html">cg</a></li><li class="progresscurrent">cgl</li><li class="progresssection"><a href="5-cgt.html">cgt</a></li><li class="progresssection"><a href="5-dt.html">dt</a></li><li class="progresssection"><a href="5-pv.html">pv</a></li><li class="progresssection"><a href="5-ts.html">ts</a></li><li class="progresschapter"><a href="6-dlg.html">6</a></li><li class="progressnext"><a href="5-cgt.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

